home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 22 code / Paper Juggling / PaperJugglingApp.c < prev    next >
Encoding:
Text File  |  1995-04-19  |  12.9 KB  |  552 lines  |  [TEXT/MMCC]

  1. //---------------------------------------------------------------------
  2. //---------------------------------------------------------------------
  3. //
  4. //    Horrible Rickety Shell, by Dave Johnson
  5. //
  6. //    © Copyright 1985 - 1995 Anyone Who Wants It,
  7. //    All Rights Energetically Hurled as far away from me as possible.
  8. //    Use at your own (considerable) risk.
  9.  
  10.  
  11. #include    "PaperJuggling.h"
  12. #include    <Folders.h>
  13. #include    <Scrap.h>
  14.  
  15. // The shell globals we need
  16. extern MenuHandle    gShellMenuHandles[];
  17. extern short        gDocTitleHeight, gDocFrameWidth;
  18.  
  19. // App Globals
  20. MenuHandle            gAppMenuHandles[kNumAppMenus];     //  The menus we add to the shell 
  21.  
  22. // GX globals
  23. Boolean                gDebugging = true;            // If gDebugging = TRUE, errors and notices will be posted.
  24. Boolean                gGiveMeValidation = true;    // if gGiveMeValidation = TRUE, run-time validation occurs.
  25. long                gGraphicsHeapSize = 600;    // pretty big
  26. GXPrintingEventUPP    gOurPrintingOverrideUPP;
  27. gxGraphicsClient    gGraphicsClient;
  28.  
  29. //  Called by the Shell at startup time 
  30. Boolean AppInit(void)
  31. {
  32.     MenuHandle        mhndl;
  33.     
  34.     //  Add the "Juggle" menu 
  35.     mhndl = GetMenu(kJuggleMenuID);
  36.     if(mhndl == nil)
  37.     {
  38.         DoErrorAlert(kNoResStr, 0);
  39.         return false;
  40.     }
  41.     (*mhndl)->menuID = kJuggleMenuID;
  42.     InsertMenu(mhndl, 0);
  43.     DisableItem(mhndl, 0); //  Disable the menu until user opens a file 
  44.     gAppMenuHandles[kJuggleMenu] = mhndl;
  45.         
  46.     DrawMenuBar();
  47.     
  48.     // Initialize global graphic objects
  49.     InitCommonGraphicObjects();
  50.     return(true);
  51. }
  52.  
  53. //   A chance to pre-handle an event 
  54. Boolean AppDoEvent(EventRecord *event)
  55. {
  56.     Boolean            handled = false;
  57.     CursHandle        curs;
  58.     
  59.     // !!! be more efficient here
  60.     // Adjust cursor
  61.     if(event->modifiers & optionKey)
  62.     {
  63.         curs = GetCursor(kThumbCursorID);
  64.         SetCursor(*curs);
  65.     }
  66.     else
  67.         SetCursor(&qd.arrow);
  68.  
  69.     return handled;
  70. }
  71.  
  72. // Called to handle an activate event
  73. void AppActivate(WindowPtr wind, Boolean activate)
  74. {
  75. }
  76.  
  77. // Called when a window needs updating. BeginUpdate() has already been called, and the 
  78. // port is set to the appropriate window
  79. void AppUpdate(WindowPtr wind)
  80. {
  81.     // Draw the content
  82.     AppDrawContent(wind);
  83. }
  84.  
  85. // Draw the content now, assuming the port, clip, etc. are all set up
  86. void AppDrawContent(WindowPtr wind)
  87. {
  88.     // Draw the page shape
  89.     GXDrawShape(GetWindowGXShape(wind));
  90.     GXDrawShape (GetDocFadedThrowsPict(wind));
  91. }
  92.  
  93. // Called when the shell recieves a null event.
  94. void AppIdle(EventRecord *Event)
  95. {
  96. }
  97.  
  98. /* Called when there is a click in the content of a window. The port is already set to 
  99. the window, and thePt is in local coords.  */
  100. void AppClick(Point thePt, WindowPtr wind, Boolean doubleClick, EventRecord *eventptr)
  101. {
  102.     DoJuggleClick(wind, thePt, eventptr);
  103. }
  104.  
  105. //  Called when there is a keyDown event 
  106. void     AppKeyDown(char key, EventRecord *eventptr)
  107. {
  108. }
  109.  
  110. // Called after the user has resized a window. Don't forget to account for the scroll bars
  111. void AppGrowWindow(WindowPtr wind, short hSize, short vSize)
  112. {
  113. }
  114.  
  115. /* Called when the user clicks in the zoom box of a window. It calls a routine to find
  116. and install the appropriate zoom rect, then zooms it, adjusting the scroll bars and so 
  117. on */
  118. void AppZoomWindow(WindowPtr wind, short zoomDir)
  119. {
  120. }
  121.     
  122. /* Called when there is a click in the menu bar, before the menu is shown. This is
  123. the app's opportunity to enable and disable its menu items. */
  124. void AppAdjustMenus()
  125. {
  126.     MenuHandle    mhndl;
  127.     Boolean        windowUp;
  128.             
  129.     windowUp = (FrontWindow() != nil && IsAppWindow(FrontWindow()));
  130.     mhndl = gAppMenuHandles[kJuggleMenu];
  131.  
  132.     // OK, first the Juggle menu. If a window is up, then enable it
  133.     if(windowUp)
  134.         EnableItem(mhndl, 0);
  135.     else
  136.         DisableItem(mhndl, 0);
  137.     
  138.     // Patterns Menu is always enabled
  139.     
  140.     // Make sure to show results
  141.     DrawMenuBar();
  142. }    
  143.  
  144. //  called when a menu other than Apple, File, or Edit is used. 
  145. void AppMenu(short menuID, short menuItem)
  146. {
  147.     WindowPtr        wind = FrontWindow();
  148.     
  149.     switch(menuID)
  150.     {
  151.         case kJuggleMenuID:
  152.             switch(menuItem)
  153.             {
  154.                 case iResizeJuggle:
  155.                     wind = ResizeJuggle(wind);
  156.                     if(wind != nil)
  157.                     {
  158.                         SetPort(wind);
  159.                         EraseRect(&wind->portRect);
  160.                         InvalRect(&wind->portRect);
  161.                     }
  162.                     else
  163.                         SysBeep(10);
  164.                     break;
  165.                     
  166.                 case iAddJuggler:
  167.                     if(AddJuggler(GetWindowJuggle(wind)))
  168.                     {
  169.                         SetPort(wind);
  170.                         EraseRect(&wind->portRect);
  171.                         InvalRect(&wind->portRect);
  172.                         AdjustScrollbars(wind, false);
  173.                     }
  174.                     else
  175.                         SysBeep(10);
  176.                     break;
  177.                 
  178.                 default:
  179.                     break;
  180.             }
  181.             break;
  182.         
  183.         default:
  184.             break;
  185.     }
  186. }
  187.  
  188. // Called when the user selects "New" from the File menu, and at other various times            
  189. WindowPtr AppNew(short numJugglers, short numCounts)
  190. {
  191.     WindowPtr    wind = nil;
  192.     OSErr        err = -1;
  193.     DocHandle    newDoc;
  194.     CursHandle    curs;
  195.  
  196.     // If no size specified, ask user how big to make it
  197.     if(numJugglers <= 0)
  198.         DoJuggleSizeDialog(&numJugglers, &numCounts);
  199.  
  200.     // if user canceled, return
  201.     if(numJugglers == 0)
  202.         return nil;
  203.     
  204.     // Set cursor to watch
  205.     curs = GetCursor(watchCursor);
  206.     SetCursor(*curs);
  207.     
  208.     // Get a new window
  209.     wind = GetNewWindow(kWindResourceID, nil, (WindowPtr)-1L);
  210.     if(wind != nil)
  211.     {
  212.         // Allocate the document structure
  213.         newDoc = (DocHandle)NewHandleClear(sizeof(DocumentRecord));
  214.         if(newDoc != nil)
  215.         {
  216.             // store the doc in the window
  217.             SetWRefCon(wind, (long)newDoc);
  218.             
  219.             // Initialize the standard document stuff
  220.             err = InitStdDoc(wind);
  221.             if(err == noErr)
  222.             {
  223.                 // Try to set up the juggle.
  224.                 err = InitJuggle(wind, numJugglers, numCounts);
  225.                 if(err == noErr)
  226.                 {
  227.                     //  Finally, position and show the window
  228.                     SetUpAndShowWindow(wind);
  229.                 }
  230.             }
  231.         }
  232.     }
  233.         
  234.     // Clean up if there were errors        
  235.     if(err != noErr)
  236.     {
  237.         DoErrorAlert(kNoMemStr, 0);
  238.         if(newDoc != nil)
  239.         {
  240.             DisposeHandle((Handle)newDoc);
  241.             newDoc = nil;
  242.         }
  243.         if(wind != nil)
  244.         {
  245.             DisposeWindow(wind);
  246.             wind = nil;
  247.         }
  248.     }
  249.  
  250.     // Set cursor back to arrow
  251.     SetCursor(&qd.arrow);
  252.     
  253.     // return window pointer (possibly nil)
  254.     return wind;
  255. }
  256.  
  257. /* Called when the user selects "Open" from the File menu. */
  258. void    AppOpen(void)
  259. {
  260.     SFTypeList            typeList;
  261.     short                err;
  262.     StandardFileReply    reply;
  263.     
  264.     /* only show JUGL files */
  265.     typeList[0] = kJuggleFileType;
  266.     
  267.     /* Standard File Dialog, system 7 style */
  268.     StandardGetFile(nil, 1, typeList, &reply);
  269.     
  270.     /* If they clicked "open"... */
  271.     if(reply.sfGood == true)
  272.     {
  273.         /* A big gnarly routine that sets everything up and reads in the juggle */
  274.         err = OpenJuggleFile(&reply.sfFile, nil);
  275.         if(err != noErr)
  276.             SysBeep(10);
  277.     }
  278. }
  279.  
  280.  
  281. // Called when the window should be closed, assume saving has happened, if necessary        
  282. void AppClose(WindowPtr wind)
  283. {
  284.     DocHandle doc;
  285.         
  286.     doc = GetWindowDoc(wind);
  287.     if(doc != nil)
  288.     {
  289.         if((*doc)->docPage != nil)
  290.             GXDisposeShape((*doc)->docPage);     // Dispose of this doc's shape.
  291.         if((*doc)->docJob != nil)
  292.             GXDisposeJob((*doc)->docJob);        // Dispose of this doc's print job.
  293.             
  294.         // Clean up the juggle bits
  295.         CleanUpJuggle(wind, true);
  296.         
  297.         // Finally kill the doc/juggle itself
  298.         DisposeHandle((Handle)doc);
  299.     }
  300.     DisposeWindow(wind);
  301. }
  302.  
  303. /* Called when the user selects "Save" from the File menu. Returns a boolean that is 
  304.     false only if AppSaveAs() is called and the user cancels the save, or if there is an
  305.     error. */
  306. Boolean    AppSave(WindowPtr wind)
  307. {
  308.     OSErr            err = noErr;
  309.     Boolean            success = true;
  310.     JuggleHandle    aJuggle;
  311.  
  312.     /* Get the juggle in question */
  313.     aJuggle = GetWindowJuggle(wind);
  314.     if(aJuggle == nil)
  315.         return true; // means "cancelled"
  316.         
  317.     /* Check the file name in our window's spec. If empty, do save as, else save */
  318.     if((*aJuggle)->fileSpec.name[0] == 0)
  319.     {
  320.         success = AppSaveAs(wind);
  321.     }
  322.     else    /* a regular save, it's been saved before */
  323.     {
  324.         /* Write the data to the file */
  325.         err = SaveJuggle(aJuggle);
  326.         
  327.         /* It's possible that the user switched to the finder and deleted the
  328.             file or ejected the disk it's on, so let's check the error. If it's 
  329.             fnfErr or nsvErr, do a SaveAs */
  330.         if(err == fnfErr || err == nsvErr)
  331.         {
  332.             err = noErr;
  333.             success = AppSaveAs(wind);
  334.         }
  335.         
  336.         if(err == noErr)
  337.             /* Successful save, so set dirty flag to false */
  338.             (*aJuggle)->dirty = false;
  339.         else
  340.         {
  341.             success = false;
  342. //            SysBeep(10);
  343.         }
  344.     }
  345.     return success;
  346. }
  347.  
  348. /* Called when the user selects "Save As..." from the File menu. Returns a boolean that 
  349.     is true if the save ends successfuly */
  350. Boolean    AppSaveAs(WindowPtr wind)
  351. {
  352.     Str255                title, prompt = "\pSave this pattern as:";
  353.     StandardFileReply    reply;
  354.     OSErr                err = noErr;
  355.     Boolean                success = false;
  356.     JuggleHandle        aJuggle;
  357.  
  358.     /* Get the juggle in question */
  359.     aJuggle = GetWindowJuggle(wind);
  360.     if(aJuggle == nil)
  361.         return true; // !!!
  362.         
  363.     // Get the title
  364.     GetWTitle(wind, title);
  365.  
  366.     /* put up Standard File Dialog */
  367.     StandardPutFile(prompt, title,  &reply);
  368.     
  369.     /* If user clicked Save, do it */
  370.     if(reply.sfGood == true)
  371.     {
  372.         /* If we are replacing an existing file, we call one routine, if we are 
  373.             creating a new one, another routine */
  374.         if(reply.sfReplacing)
  375.             err = JuggleToExistingFile(&reply.sfFile, aJuggle);
  376.         else
  377.             err = JuggleToNewFile(&reply.sfFile, aJuggle);
  378.         
  379.         if(err == noErr)
  380.         {
  381.             /*    Successful save, so rename the window, and set the dirty flag */
  382.             SetWTitle(wind, reply.sfFile.name);
  383.             (*aJuggle)->dirty = false;
  384.  
  385.             // Save the new file in the juggle, and signal success
  386.             (*aJuggle)->fileSpec = reply.sfFile;
  387.             success = true;
  388.         }
  389.     }
  390.     
  391.     return success;
  392. }
  393.  
  394. //  Called when the user selects "Page Setup..." from the File menu. 
  395. void AppPageSetup(WindowPtr wind)
  396. {
  397.     gxDialogResult    result;
  398.     
  399.     if(wind == nil)
  400.         return;
  401.     DoGXFormatDialog(wind, &result);
  402. }
  403.  
  404. //  Called when the user selects "Print…" from the File menu. 
  405. OSErr AppPrint(WindowPtr wind)
  406. {
  407.     if(wind == nil)
  408.         return -1;
  409.     return DoGXPrinting(wind);
  410. }
  411.  
  412. //  Called when the user selects "Print One" from the File menu. 
  413. OSErr AppPrintOne(WindowPtr wind)
  414. {
  415.     gxShape            pageShape;
  416.     OSErr            err = -1;    // assume failure
  417.     JuggleHandle    aJuggle;
  418.     
  419.     /* Get the juggle in question */
  420.     aJuggle = GetWindowJuggle(wind);
  421.     if(aJuggle == nil)
  422.         return err;
  423.     
  424.     // Make a page to print
  425.     pageShape = MakePrintingShape(aJuggle);
  426.     if(pageShape != nil)
  427.     {
  428.         // Call the shell to print it
  429.         err = DoGXPrintOne(wind, pageShape);
  430.     
  431.         // Clean up
  432.         GXDisposeShape(pageShape);
  433.     }
  434.     
  435.     return err;
  436. }
  437.  
  438. //  Called when the user selects "Undo" from the Edit menu. 
  439. void AppUndo(void)
  440. {
  441. }
  442.  
  443. //  Called when the user selects "Cut" from the Edit menu. 
  444. void AppCut(void)
  445. {
  446. }
  447.  
  448. //  Called when the user selects "Copy" from the Edit menu. 
  449. OSErr AppCopy(void)
  450. {
  451.     return noErr;
  452. }            
  453.             
  454. //  Called when the user selects "Paste" from the Edit menu. 
  455. void AppPaste(void)
  456. {
  457. }
  458.  
  459. //  Called when the user selects "Clear" from the Edit menu. 
  460. void AppClear(void)
  461. {
  462. }
  463.  
  464. //  Called when the shell is about to quit, saving has already happened. 
  465. void AppCleanUp(void)
  466. {
  467.     WindowPtr    wind;
  468.     
  469.     //  Close any windows (assumed already saved, if necessary),
  470.     // which also kills the scrollBars 
  471.     while((wind = FrontWindow()) != nil)
  472.         AppClose(wind);
  473.     
  474.     // If GX is active, kill it
  475.     if(gGraphicsClient != nil)
  476.     {
  477.         // Clean up the global objects
  478.         KillCommonGraphicObjects();
  479.         TearDownGX();
  480.         gGraphicsClient = nil;
  481.     }
  482. }
  483.  
  484. Boolean SetUpGX(void)
  485. {
  486.     Boolean result = false; // assume failure
  487.     
  488.     // The GXNewGraphicsClient routine defines the graphics heap size.  If you do not make this
  489.     // call, the GX graphics engine will create this heap automatically.  How?  It will create
  490.     // a heap which is a percentage of your application's ideal memory foot print.  This call
  491.     // allows you to explicity define the ammount of memory used by the graphics system for
  492.     // its graphics objects heap.
  493.  
  494.     gGraphicsClient = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
  495.  
  496.     if ( gGraphicsClient )
  497.     {
  498.         // If gDebugging = TRUE, you will receive graphics library errors & notices will be posted.
  499.         // This functionality will only work with the "debugging" version of QuickDraw GX.  If you
  500.         // don't have the debugging version installed, these functions will not work. 
  501.     
  502.         if (gDebugging)
  503.         {
  504.             SetGraphicsLibraryErrors ();
  505.             SetGraphicsLibraryNotices();    
  506.         }
  507.     
  508.         // Set gGiveMeValidation to TRUE if you want run-time validation. As you increase the amount
  509.         // of validation, The drawing speed will SLOW down due to all of the internal checking. 
  510.             
  511.         // gxPublicValidation will check parameters to public routines. For additional details
  512.         // regarding the various levels of validation, see "Inside Macintosh: QuickDraw GX
  513.         // Environment and Utilties."
  514.     
  515.         if (gGiveMeValidation)
  516.             GXSetValidation(gxPublicValidation); 
  517.     
  518.         // Initialize the new graphics and printing environments.
  519.     
  520.         if ( GXGetGraphicsError( nil ) != out_of_memory ) 
  521.         {
  522.             OSErr    err;
  523.             
  524.             GXEnterGraphics();
  525.             err = GXInitPrinting();
  526.         
  527.             // Initialize the other managers, if no errors occurred.
  528.             if ( err == noErr )
  529.             {
  530.                 InitCommonColors();
  531.                 // Initialize our printing event override UPP
  532.                 gOurPrintingOverrideUPP = NewGXPrintingEventProc(MyGXPrintingEventOverride);
  533.                 // success!
  534.                 result = true;
  535.             }
  536.         }
  537.     }
  538.     return result;
  539. }
  540.     
  541.  
  542. void TearDownGX(void)
  543. {
  544.     DisposeCommonColors();
  545.     GXExitPrinting();    // Close the new printing mgr. 
  546.     GXExitGraphics();        // Deallocate all of the default structures
  547.     GXDisposeGraphicsClient(gGraphicsClient);
  548.     DisposeRoutineDescriptor(gOurPrintingOverrideUPP);
  549. }
  550.  
  551.  
  552.